package com.jch.sc.future;

import com.jch.sc.msg.Response;

import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

public class SyncWriteFuture implements WriteFuture<Response> {

    // CountDownLatch是一种通用的同步工具，可用于多种目的。
    // 计数为 1 的CountDownLatch用作简单的开/关锁存器或门：
    //  调用await所有线程在门处等待，直到它被调用countDown的线程countDown 。
    // 其他用法见： https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/CountDownLatch.html
    private CountDownLatch latch = new CountDownLatch(1);
    private final long begin = System.currentTimeMillis();
    private long timeout;
    private Response response;
    private final String requestId;
    private boolean writeResult;
    private Throwable cause;
//    private boolean isTimeout = false;


    public SyncWriteFuture(String requestId) {
        this.requestId = requestId;
    }

    public SyncWriteFuture(long timeout, String requestId) {
        this.timeout = timeout;
        this.requestId = requestId;
        writeResult = true;
//        isTimeout = false;
    }

    @Override
    public Throwable cause() {
        return cause;
    }

    @Override
    public void setCause(Throwable cause) {
        this.cause = cause;
    }

    @Override
    public boolean isWriteSuccess() {
        return writeResult;
    }

    @Override
    public void setWriteResult(boolean result) {
        this.writeResult = result;
    }

    @Override
    public String resultId() {
        return requestId;
    }

    @Override
    public Response response() {
        return response;
    }

    @Override
    public void setResponse(Response response) {
        this.response = response;
        latch.countDown(); // 释放 或 关闭
    }

    @Override
    public boolean isTimeout() {
//        if (isTimeout) return isTimeout;
        return System.currentTimeMillis() - begin > timeout; // 计算是否超时
    }

    // 尝试取消该任务
    @Override
    public boolean cancel(boolean mayInterruptIfRunning) {
        return true;
    }

    // 如果此任务在正常完成之前被取消，则返回true
    @Override
    public boolean isCancelled() {
        return false;
    }

    // 如果此任务完成，则返回true 。 完成可能是由于正常终止、异常或取消——在所有这些情况下，此方法将返回true 。
    @Override
    public boolean isDone() {
        return false;
    }

    // 获取计算结果，会等待计算完成，在获取计算结果。
    @Override
    public Response get() throws InterruptedException, ExecutionException {
        latch.wait(); // 等待计算完成
        return response;
    }

    // 如有必要，最多等待给定的计算完成时间，然后检索其结果（如果可用）。
    @Override
    public Response get(long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException {
        if (latch.await(timeout, unit)) { // 等待指定时间
            return response;
        }
        return null;
    }
}
